/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package econutri.servicos.sujestao;

import econutri.persistencia.entidades.Alimento;
import econutri.util.Utils;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lomtools.persistence.GenericDAO;

/**
 *
 * @author Leonardo Oliveira Moreira
 * 
 */
public class ProcessarModeloMatematicoXMLServlet extends HttpServlet {

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("application/xml;charset=ISO-8859-1");
        String xml = "";

        double custoTotal = Double.parseDouble(request.getParameter("custoTotal"));
        double vet = Double.parseDouble(request.getParameter("vet"));
        
        double carboidratoMin = Double.parseDouble(request.getParameter("carboidratoMin"));
        double proteinaMin = Double.parseDouble(request.getParameter("proteinaMin"));
        double lipidioMin = Double.parseDouble(request.getParameter("lipidioMin"));
        double calcioMin = Double.parseDouble(request.getParameter("calcioMin"));
        double fosforoMin = Double.parseDouble(request.getParameter("fosforoMin"));
        double ferroMin = Double.parseDouble(request.getParameter("ferroMin"));
        double sodioMin = Double.parseDouble(request.getParameter("sodioMin"));
        double vitaminaAMin = Double.parseDouble(request.getParameter("vitaminaAMin"));
        double vitaminaB1Min = Double.parseDouble(request.getParameter("vitaminaB1Min"));
        double vitaminaB2Min = Double.parseDouble(request.getParameter("vitaminaB2Min"));
        double niacinaMin = Double.parseDouble(request.getParameter("niacinaMin"));
        double vitaminaCMin = Double.parseDouble(request.getParameter("vitaminaCMin"));
        double fibraMin = Double.parseDouble(request.getParameter("fibraMin"));
        double colesterolMin = Double.parseDouble(request.getParameter("colesterolMin"));
        double carboidratoMax = Double.parseDouble(request.getParameter("carboidratoMax"));
        double proteinaMax = Double.parseDouble(request.getParameter("proteinaMax"));
        double lipidioMax = Double.parseDouble(request.getParameter("lipidioMax"));
        double calcioMax = Double.parseDouble(request.getParameter("calcioMax"));
        double fosforoMax = Double.parseDouble(request.getParameter("fosforoMax"));
        double ferroMax = Double.parseDouble(request.getParameter("ferroMax"));
        double sodioMax = Double.parseDouble(request.getParameter("sodioMax"));
        double vitaminaAMax = Double.parseDouble(request.getParameter("vitaminaAMax"));
        double vitaminaB1Max = Double.parseDouble(request.getParameter("vitaminaB1Max"));
        double vitaminaB2Max = Double.parseDouble(request.getParameter("vitaminaB2Max"));
        double niacinaMax = Double.parseDouble(request.getParameter("niacinaMax"));
        double vitaminaCMax = Double.parseDouble(request.getParameter("vitaminaCMax"));
        double fibraMax = Double.parseDouble(request.getParameter("fibraMax"));
        double colesterolMax = Double.parseDouble(request.getParameter("colesterolMax"));
        
        List<AlimentoSugestao> sugestaoList = new ArrayList<AlimentoSugestao>();
        
        Enumeration<String> parameterNames = request.getParameterNames();
        List<String> variavelList = new ArrayList<String>();
        while (parameterNames.hasMoreElements()) {
            String param = parameterNames.nextElement();
            if (param.startsWith("X")) {
                variavelList.add(param);
            }
        }
        int x = 1;
        while (variavelList.size() > 0) {
            for (int i = 0; i < variavelList.size(); i++) {
                if (variavelList.get(i).equals("X" + x)) {
                    String value = request.getParameter(variavelList.get(i));
                    String[] valueSplit = value.split("@");
                    AlimentoSugestao a = new AlimentoSugestao();
                    a.setVariavel(variavelList.get(i));
                    a.setCodigo(Long.parseLong(valueSplit[0]));
                    a.setQuantidadeMinima(Double.parseDouble(valueSplit[1]));
                    sugestaoList.add(a);
                    variavelList.remove(i);
                    x++;
                    break;
                }
            }
        }

        try {
            for (AlimentoSugestao a : sugestaoList) {

                GenericDAO dao = new GenericDAO();
                String sql = "SELECT " +
                        "al.codigo, al.descricao, al.quantidade, al.carboidrato, al.proteina, al.lipidio, al.calcio, al.fosforo, al.ferro, al.sodio, al.vitaminaa, al.vitaminab1, al.vitaminab2, al.niacina, al.vitaminac, al.fibra, al.colesterol, al.preco " +
                      "FROM alimento al " +
                      "WHERE al.codigo = " + a.getCodigo();
                ResultSet rsSugestao = dao.executeQuery(sql);
                while (rsSugestao != null && rsSugestao.next()) {

                    a.setCodigo(rsSugestao.getLong("codigo"));
                    a.setDescricao(rsSugestao.getString("descricao"));
                    a.setQuantidade(rsSugestao.getDouble("quantidade")/100);

                    a.setCarboidrato(Utils.formatDoubleValue(rsSugestao.getDouble("carboidrato")/100));
                    a.setProteina(Utils.formatDoubleValue(rsSugestao.getDouble("proteina")/100));
                    a.setLipidio(Utils.formatDoubleValue(rsSugestao.getDouble("lipidio")/100));

                    a.setCalcio(Utils.formatDoubleValue(rsSugestao.getDouble("calcio")/100));
                    a.setFosforo(Utils.formatDoubleValue(rsSugestao.getDouble("fosforo")/100));
                    a.setFerro(Utils.formatDoubleValue(rsSugestao.getDouble("ferro")/100));
                    a.setSodio(Utils.formatDoubleValue(rsSugestao.getDouble("sodio")/100));
                    a.setVitaminaA(Utils.formatDoubleValue(rsSugestao.getDouble("vitaminaa")/100));
                    a.setVitaminaB1(Utils.formatDoubleValue(rsSugestao.getDouble("vitaminab1")/100));
                    a.setVitaminaB2(Utils.formatDoubleValue(rsSugestao.getDouble("vitaminab2")/100));
                    a.setNiacina(Utils.formatDoubleValue(rsSugestao.getDouble("niacina")/100));
                    a.setVitaminaC(Utils.formatDoubleValue(rsSugestao.getDouble("vitaminac")/100));
                    a.setFibra(Utils.formatDoubleValue(rsSugestao.getDouble("fibra")/100));
                    a.setColesterol(Utils.formatDoubleValue(rsSugestao.getDouble("colesterol")/100));

                    a.setPreco(Utils.formatDoubleValue(rsSugestao.getDouble("preco")/100));

                    a.setCalorias(Utils.formatDoubleValue(Utils.getCalorias(a.getQuantidade(), a.getCarboidrato(), a.getProteina(), a.getLipidio())));
                }
                dao.close();
            }
        } catch (SQLException ex) {

        }
        String pl = "";
        pl += "MIN ";
        for (int i = 0; i < sugestaoList.size(); i++) {
            AlimentoSugestao a = sugestaoList.get(i);
            pl += a.getPreco() + a.getVariavel();
            if (i < sugestaoList.size() - 1) {
                pl += " + ";
            }
        }
        pl += "\n";
        pl += "\n";
        pl += "SUBJECT TO\n";
        pl += "\n";
        pl += "! Restrição de valor máximo a pagar";
        pl += "\n";
        for (int i = 0; i < sugestaoList.size(); i++) {
            AlimentoSugestao a = sugestaoList.get(i);
            pl += a.getPreco() + a.getVariavel();
            if (i < sugestaoList.size() - 1) {
                pl += " + ";
            }
        }
        pl += " <= " + custoTotal + "\n";
        /* Restrição de VET */
        pl += "\n";
        pl += "! Restrição de VET";
        pl += "\n";
        String tempVet = "";
        for (int i = 0; i < sugestaoList.size(); i++) {
            AlimentoSugestao a = sugestaoList.get(i);
            tempVet += a.getCalorias() + a.getVariavel();
            if (i < sugestaoList.size() - 1) {
                tempVet += " + ";
            }
        }
        pl += tempVet + " >= " + (vet - 50) + "\n";
        pl += tempVet + " <= " + (vet + 50) + "\n";
        /* Macronutrientes */
        String[] macroNutrientes = new String[3];
        for (int i = 0; i < macroNutrientes.length; i++) {
            macroNutrientes[i] = "";
        }
        for (int i = 0; i < sugestaoList.size(); i++) {
            AlimentoSugestao a = sugestaoList.get(i);
            if (a.getCarboidrato() > 0) {
                macroNutrientes[0] += a.getCarboidrato() + a.getVariavel();
            }
            else {
                macroNutrientes[0] += "";
            }
            if (a.getProteina() > 0) {
                macroNutrientes[1] += a.getProteina() + a.getVariavel();
            }
            else {
                macroNutrientes[1] += "";
            }
            if (a.getLipidio() > 0) {
                macroNutrientes[2] += a.getLipidio() + a.getVariavel();
            }
            else {
                macroNutrientes[2] += "";
            }
            if (i < sugestaoList.size() - 1) {
                for (int j = 0; j < macroNutrientes.length; j++)
                    macroNutrientes[j] += " + ";
            }
        }
        for (int j = 0; j < macroNutrientes.length; j++) {
            macroNutrientes[j] = macroNutrientes[j].replaceAll("[+ +]+", " + ");
            if (macroNutrientes[j].startsWith(" + ")) {
                macroNutrientes[j] = macroNutrientes[j].substring(" + ".length());
            }
            if (macroNutrientes[j].endsWith(" + ")) {
                macroNutrientes[j] = macroNutrientes[j].substring(0, macroNutrientes[j].length() - " + ".length());
            }
        }
        /* Micronutrientes */
        String[] microNutrientes = new String[11];
        for (int i = 0; i < microNutrientes.length; i++) {
            microNutrientes[i] = "";
        }
        for (int i = 0; i < sugestaoList.size(); i++) {
            AlimentoSugestao a = sugestaoList.get(i);
            if (a.getCalcio() > 0) {
                microNutrientes[0] += a.getCalcio() + a.getVariavel();
            }
            else {
                microNutrientes[0] += "";
            }
            if (a.getFosforo() > 0) {
                microNutrientes[1] += a.getFosforo() + a.getVariavel();
            }
            else {
                microNutrientes[1] += "";
            }
            if (a.getFerro() > 0) {
                microNutrientes[2] += a.getFerro() + a.getVariavel();
            }
            else {
                microNutrientes[2] += "";
            }

            if (a.getSodio() > 0) {
                microNutrientes[3] += a.getSodio() + a.getVariavel();
            }
            else {
                microNutrientes[3] += "";
            }
            if (a.getVitaminaA() > 0) {
                microNutrientes[4] += a.getVitaminaA() + a.getVariavel();
            }
            else {
                microNutrientes[4] += "";
            }
            if (a.getVitaminaB1() > 0) {
                microNutrientes[5] += a.getVitaminaB1() + a.getVariavel();
            }
            else {
                microNutrientes[5] += "";
            }

            if (a.getVitaminaB2() > 0) {
                microNutrientes[6] += a.getVitaminaB2() + a.getVariavel();
            }
            else {
                microNutrientes[6] += "";
            }
            if (a.getNiacina() > 0) {
                microNutrientes[7] += a.getNiacina() + a.getVariavel();
            }
            else {
                microNutrientes[7] += "";
            }
            if (a.getVitaminaC() > 0) {
                microNutrientes[8] += a.getVitaminaC() + a.getVariavel();
            }
            else {
                microNutrientes[8] += "";
            }

            if (a.getFibra() > 0) {
                microNutrientes[9] += a.getFibra() + a.getVariavel();
            }
            else {
                microNutrientes[9] += "";
            }
            if (a.getColesterol() > 0) {
                microNutrientes[10] += a.getColesterol() + a.getVariavel();
            }
            else {
                microNutrientes[10] += "";
            }
            if (i < sugestaoList.size() - 1) {
                for (int j = 0; j < microNutrientes.length; j++)
                    microNutrientes[j] += " + ";
            }
        }
        for (int j = 0; j < microNutrientes.length; j++) {
            microNutrientes[j] = microNutrientes[j].replaceAll("[+ +]+", " + ");
            if (microNutrientes[j].startsWith(" + ")) {
                microNutrientes[j] = microNutrientes[j].substring(" + ".length());
            }
            if (microNutrientes[j].endsWith(" + ")) {
                microNutrientes[j] = microNutrientes[j].substring(0, microNutrientes[j].length() - " + ".length());
            }
        }

        pl += "\n";
        pl += "! Restrição de valor mínimo (macro nutrientes)";
        pl += "\n";
        if (macroNutrientes[0].trim().length() > 0) {
            pl += macroNutrientes[0] + " >= " + carboidratoMin + "\n";
        }
        if (macroNutrientes[1].trim().length() > 0) {
            pl += macroNutrientes[1] + " >= " + proteinaMin + "\n";
        }
        if (macroNutrientes[2].trim().length() > 0) {
            pl += macroNutrientes[2] + " >= " + lipidioMin + "\n";
        }
        pl += "\n";
        pl += "! Restrição de valor mínimo (micro nutrientes)";
        pl += "\n";
        if (microNutrientes[0].trim().length() > 0) {
            pl += microNutrientes[0] + " >= " + calcioMin + "\n";
        }
        if (microNutrientes[1].trim().length() > 0) {
            pl += microNutrientes[1] + " >= " + fosforoMin + "\n";
        }
        if (microNutrientes[2].trim().length() > 0) {
            pl += microNutrientes[2] + " >= " + ferroMin + "\n";
        }
        if (microNutrientes[3].trim().length() > 0) {
            pl += microNutrientes[3] + " >= " + sodioMin + "\n";
        }
        if (microNutrientes[4].trim().length() > 0) {
            pl += microNutrientes[4] + " >= " + vitaminaAMin + "\n";
        }
        if (microNutrientes[5].trim().length() > 0) {
            pl += microNutrientes[5] + " >= " + vitaminaB1Min + "\n";
        }
        if (microNutrientes[6].trim().length() > 0) {
            pl += microNutrientes[6] + " >= " + vitaminaB2Min + "\n";
        }
        if (microNutrientes[7].trim().length() > 0) {
            pl += microNutrientes[7] + " >= " + niacinaMin + "\n";
        }
        if (microNutrientes[8].trim().length() > 0) {
            pl += microNutrientes[8] + " >= " + vitaminaCMin + "\n";
        }
        if (microNutrientes[9].trim().length() > 0) {
            pl += microNutrientes[9] + " >= " + fibraMin + "\n";
        }
        if (microNutrientes[10].trim().length() > 0) {
            pl += microNutrientes[10] + " >= " + colesterolMin + "\n";
        }
        pl += "\n";
        pl += "! Restrição de valor máximo (macro nutrientes)";
        pl += "\n";
        if (macroNutrientes[0].trim().length() > 0) {
            pl += macroNutrientes[0] + " <= " + carboidratoMax + "\n";
        }
        if (macroNutrientes[1].trim().length() > 0) {
            pl += macroNutrientes[1] + " <= " + proteinaMax + "\n";
        }
        if (macroNutrientes[2].trim().length() > 0) {
            pl += macroNutrientes[2] + " <= " + lipidioMax + "\n";
        }
        pl += "\n";
        pl += "! Restrição de valor máximo (micro nutrientes)";
        pl += "\n";
        if (microNutrientes[0].trim().length() > 0) {
            pl += microNutrientes[0] + " <= " + calcioMax + "\n";
        }
        if (microNutrientes[1].trim().length() > 0) {
            pl += microNutrientes[1] + " <= " + fosforoMax + "\n";
        }
        if (microNutrientes[2].trim().length() > 0) {
            pl += microNutrientes[2] + " <= " + ferroMax + "\n";
        }
        if (microNutrientes[3].trim().length() > 0) {
            pl += microNutrientes[3] + " <= " + sodioMax + "\n";
        }
        if (microNutrientes[4].trim().length() > 0) {
            pl += microNutrientes[4] + " <= " + vitaminaAMax + "\n";
        }
        if (microNutrientes[5].trim().length() > 0) {
            pl += microNutrientes[5] + " <= " + vitaminaB1Max + "\n";
        }
        if (microNutrientes[6].trim().length() > 0) {
            pl += microNutrientes[6] + " <= " + vitaminaB2Max + "\n";
        }
        if (microNutrientes[7].trim().length() > 0) {
            pl += microNutrientes[7] + " <= " + niacinaMax + "\n";
        }
        if (microNutrientes[8].trim().length() > 0) {
            pl += microNutrientes[8] + " <= " + vitaminaCMax + "\n";
        }
        if (microNutrientes[9].trim().length() > 0) {
            pl += microNutrientes[9] + " <= " + fibraMax + "\n";
        }
        if (microNutrientes[10].trim().length() > 0) {
            pl += microNutrientes[10] + " <= " + colesterolMax + "\n";
        }
        pl += "\n";
        pl += "! Restrição de não negatividade das variáveis";
        pl += "\n";
        for (AlimentoSugestao a : sugestaoList) {
            pl += a.getVariavel() + " >= " + a.getQuantidadeMinima() + "\n";
        }
        if (pl.endsWith(", \n")) {
            pl = pl.substring(0, pl.lastIndexOf(", \n"));
        }
        pl += "\n";
        pl += "END";
        xml += "<result>";

            xml += "<pl>";
            String plHtml = pl;
            plHtml = plHtml.replaceAll("<", "&lt;");
            plHtml = plHtml.replaceAll("<", "&gt;");
            plHtml = plHtml.replaceAll("\n", "&lt;br/&gt;");
                xml += plHtml;
            xml += "</pl>";
        xml += "</result>";
        PrintWriter out = response.getWriter();
        try {
            out.println(xml);
        } finally {
            out.close();
        }
    } 

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    } 

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

}
